import { fetchData } from './store.js'

export class Waver {
  size = 1000 // 采样个数

  peroid = 1000 // 周期

  total = 0 // 总共周期数

  range = 1000 // 显示范围

  pixels = 1000 // 显示器分辨率 

  timer = null // 定时器

  currentPeroidNum = null // 当前周期数

  // get offset () { // 采样位置
  //   if (this.currentPeroidNum != null) return this.currentPeroidNum * this.size
  //   return this.total * this.size
  // } 

  // 刷新频率
  interval = 200

  // 当前帧数
  frame = 1

  get duration () { // 总时长
    return this.total * this.peroid
  }

  get currentPeroidRange () { // 当前周期范围
    const end = this.currentPeroidNum != null ? this.currentPeroidNum : (this.total - 1 + this.frame / (1000 / this.interval))
    const start = Math.max(0, end - this.range / this.peroid)
    return [start, Math.max(start, end)]
  }

  get currentTimeRange () { // 当前时间范围
    const [start, end] = this.currentPeroidRange
    return [start * this.peroid, end * this.peroid]
  }

  events = new Map()

  genPoints () {
    const [start, end] = this.currentPeroidRange
    // console.log('0000', start, end, this.frame)
    const items = fetchData(start * this.size, (end - start) * this.size)
    if (items.length > this.pixels) { // 若实际数据大于分辨率， 过滤冗余数据
      // TODO 这里需要一套好的算法，可根据数据的差异性来抽取数据，demo为平均抽取
      const ratio = Math.floor(items.length / this.pixels)
      const ret = []
      for (let i = 0; i < items.length; i++) {
        if (i % ratio === 0) ret.push(items[i])
      }
      return ret
    }
    return items
  }

  on (name, fn) {
    if (!this.events.get(name)) {
      this.events.set(name, [])
    }
    this.events.get(name).push(fn)
  }

  off (name, fn) {
    const rows = this.events.get(name) || []
    const idx = rows.findIndex(v => v === fn)
    if (idx !== -1) {
      rows.splice(idx, 1)
    }
  }

  start () {
    if (this.timer) clearInterval(this.timer)
    let lastPeroidNum = null  
    this.timer = setInterval(() => {
      if (this.frame * this.interval > this.peroid) {
        this.total++
        this.frame = 1
      }
      if (this.currentPeroidNum != null) {
        if (this.this.currentPeroidNum === lastPeroidNum) return
        lastPeroidNum = this.currentPeroidNum
      } else {
        lastPeroidNum = null
      }
      const points = this.genPoints()
      this.frame++
      const evs = this.events.get('draw')
      if (evs) {
        evs.forEach(v => {
          v({ points })
        })
      }
    }, this.interval)  
  }

  restart () {
    this.stop()
    this.total = 0
    this.scale = 1
    this.frame = 1
    this.currentPeroidNum = null
    this.start()
  }

  stop () {
    if (this.timer) clearInterval(this.timer)
  }

  // 回看
  replay (n) {
    this.currentPeroidNum =Math.floor( Math.max(0, this.total - (n / this.peroid)))
  }

  // 取消回看
  resume () {
    this.currentPeroidNum = null
  }

  // 放大/缩小
  scale (n) {
    this.range = n
    this.frame = 0
  }
}